/*
 *  Copyright 2002 by Texas Instruments Incorporated.
 *  All rights reserved. Property of Texas Instruments Incorporated.
 *  Restricted rights to use, duplicate or disclose this code are
 *  granted through contract.
 *  
 */
/*
 *  ======== thrDisplay.c ========
 */
 
#include <std.h>
#include <string.h>

// DSP/BIOS includes
#include <tsk.h>


// CSL includes
#include <csl_dat.h>

// RF5 module includes
#include <scom.h>
#include <utl.h>

// DDK
#include <fvid.h>
#include <edc.h>
#include <vport.h>
#include <vportdis.h>
#include <saa7105.h>  
                      
#include <csl_vphal.h>
#include <csl_cache.h>                      
#include <evmdm642.h>

#include <evmdm642_disParamsSDTVDefault.h>

#include "appThreads.h"

// application includes
#include "appResources.h"   /* application-wide common info */

// Thread include
#include "thrDisplay.h"

#pragma DATA_SECTION(dis_mem_temp, ".INTPROCBUFF");
#pragma DATA_ALIGN(dis_mem_temp, MEMALIGN);
unsigned char dis_mem_temp[720];

//FVID Variables
FVID_Handle disChan;
FVID_Frame *disFrameBuf;

VPORT_PortParams EVMDM642_vDisParamsPort 
  = EVMDM642_DIS_PARAMS_PORT_DEFAULT;

#ifdef _NTSC
static VPORTDIS_Params EVMDM642_vDisParamsChan 
  = EVMDM642_DIS_PARAMS_CHAN_BT656_DEFAULT(NTSC);

static SAA7105_ConfParams EVMDM642_vDisParamsSAA7105 
  = EVMDM642_DIS_PARAMS_SAA7105_SDTV_DEFAULT(NTSC720, SVIDEO);
#elif defined _PAL
static VPORTDIS_Params EVMDM642_vDisParamsChan 
  = EVMDM642_DIS_PARAMS_CHAN_BT656_DEFAULT(PAL);

static SAA7105_ConfParams EVMDM642_vDisParamsSAA7105 
  = EVMDM642_DIS_PARAMS_SAA7105_SDTV_DEFAULT(PAL720, SVIDEO);
#endif
// Local function prototypes
void yuv420to422( char *frameIn[], char *frm_out[],
				int width, int height);

/*
 *  ======== thrDisplayInit ========
 *
 */
Void thrDisplayInit()
{
    SCOM_Handle scomReceive;
    int status;
    
    EVMDM642_vDisParamsChan.segId = EXTERNALHEAP;

    EVMDM642_vDisParamsSAA7105.hI2C = EVMDM642_I2C_hI2C;

    disChan = FVID_create("/VP2DISPLAY", IOM_OUTPUT,
        &status, (Ptr)&EVMDM642_vDisParamsChan, NULL);
    
    FVID_control(disChan, VPORT_CMD_EDC_BASE+EDC_CONFIG, (Ptr)&EVMDM642_vDisParamsSAA7105);
    
    scomReceive = SCOM_create("scomDisplay", NULL);
    UTL_assert( scomReceive != NULL);
}


/*
 *  ======== thrDisplayStartup ========
 *
 */
Void thrDisplayStartup()
{
	FVID_control(disChan, VPORT_CMD_START, NULL);
}

/*
 *  ======== thrDisplayRun ========
 *
 *  Main function of Display Thread.
 */
Void thrDisplayRun() 
{
    SCOM_Handle     scomReceive, scomSend;
    Char *inBuf[3];
    Char *outBuf[3];

    UTL_logDebug1("thrDisplayRun:  task = 0x%x", TSK_self());

    // create the SCOM links (one for receiving and another for sending) 
    scomReceive = SCOM_open( "scomDisplay" );
    scomSend = SCOM_open( "scomToProcessFromDisplay" );

    UTL_assert( scomReceive != NULL );
    UTL_assert( scomSend != NULL );
    
    FVID_alloc(disChan, &disFrameBuf);

    // Main loop
    while (TRUE) { 
        ScomProcToDisp  *scombufDisp;
        
        // get a full buffer from the ProcToDisp link       
        scombufDisp = SCOM_getMsg( scomReceive, SYS_FOREVER );
        
        //Convert 420 to 422
        inBuf[Y] = scombufDisp->bufYCRCB[Y];
        inBuf[CR] = scombufDisp->bufYCRCB[CR];
        inBuf[CB] = scombufDisp->bufYCRCB[CB];
        
        outBuf[Y] = disFrameBuf->frame.iFrm.y1;
        outBuf[CR] = disFrameBuf->frame.iFrm.cr1;
        outBuf[CB] = disFrameBuf->frame.iFrm.cb1;
        
        yuv420to422(inBuf, outBuf, OPF_WIDTH, OPF_HEIGHT);
        
		FVID_exchange(disChan, &disFrameBuf);
		
        // send back descriptors of now used up source channels to Process
        SCOM_putMsg( scomSend, scombufDisp );
    }
}


void yuv420to422( char *frameIn[], char *frm_out[],
                int width, int height)
{
    char *pSrcY = frameIn[0];
    char *pSrcU = frameIn[1];
    char *pSrcV = frameIn[2];

    char *pDestY = frm_out[0];
    char *pDestU = frm_out[1];
    char *pDestV = frm_out[2];

    unsigned int id;
    unsigned int i;
    CACHE_clean(CACHE_L2ALL, 0, 0);
    for( i = 0; i < height; i++)
    {
        id = DAT_copy(pSrcY + (i * width), dis_mem_temp, width);
        id = DAT_copy(dis_mem_temp, pDestY + (i * width),  width);
    }

    for( i = 0; i < (height >> 1); i++)
    {
        id = DAT_copy(pSrcU + (i * (width >> 1)), dis_mem_temp, (width >> 1));
        id = DAT_copy(dis_mem_temp, pDestU + ((2 * i) * (width >> 1)),  (width >> 1));
        id = DAT_copy(dis_mem_temp, pDestU + ((2*i + 1)* (width >> 1)), (width >> 1));
    }

    for( i = 0; i < (height >> 1); i++)
    {
        id = DAT_copy(pSrcV + (i * (width >> 1)), dis_mem_temp, (width >> 1));
        id = DAT_copy(dis_mem_temp, pDestV + ((2*i) * (width >> 1)),   (width >> 1));
        id = DAT_copy(dis_mem_temp, pDestV + ((2*i+1) * (width >> 1)), (width >> 1));
    }
	DAT_wait(id);

   	return ;
}


